package com.cloud.point.javase;

import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
import java.lang.reflect.Proxy;

import lombok.extern.slf4j.Slf4j;

/**
 * 动态代理
 *
 * @author 24373
 * @version 1.0
 * @date 2024-07-04 16:22
 */
@Slf4j
public class TestDynamicProxy {
    public static void main(String[] args) {
        NikeFactory2 fac = new NikeFactory2();
        DynamicProxy proxyInstance = (DynamicProxy) ClothFactoryProxy2.getProxyInstance(fac);
        proxyInstance.makeProduct();
        StaticFactory proxyInstance2 = (StaticFactory) ClothFactoryProxy2.getProxyInstance(new NikeFactory());
        proxyInstance2.makeProduct();

    }
}

class ClothFactoryProxy2 {
    /**
     * obj是真实需要调用的对象；由外部传入；再用对象反射调用方法
     */
    public static Object getProxyInstance(Object obj) {
        ClothInvokeHandler handler = new ClothInvokeHandler(obj);
        return Proxy.newProxyInstance(obj.getClass().getClassLoader(), obj.getClass().getInterfaces(), handler);
    }
}

/**
 * 调用处理器；真正调用方法的地方
 */
@Slf4j
class ClothInvokeHandler implements InvocationHandler {
    private Object obj;

    public ClothInvokeHandler(Object obj) {
        this.obj = obj;
    }

   /* public void bind(Object obj) {
        this.obj = obj;
    }*/

    @Override
    public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
        log.info("{}::方法反射调用::{}", method.getName(), obj);
        Object invoke = method.invoke(obj, args);
        return invoke;
    }
}

@Slf4j
class NikeFactory2 implements DynamicProxy {
    @Override
    public void makeProduct() {
        log.info("动态生产nike衣服");
    }
}

interface DynamicProxy {
    void makeProduct();
}